
#ifndef TEXTURE_2D_H
#define TEXTURE_2D_H

// INCLUDES ********************************************************************

#include "Vector2D.h"

#include "Rectangle.h"

#include "Datatypes.h"

#include <string>

#include <vector>

#include <OpenGLES/ES1/gl.h>

#include <QuartzCore/QuartzCore.h>

// FORWARD DECLARATIONS ********************************************************

// NAMESPACES ******************************************************************

namespace 
{
    const uint32_t gBitsPerComponent = 8;
    
    const uint32_t gNumTextureCoordinates = 8;
    
    const float gDefaultTextureCoordinates[] = 
    {
        0, 1,
        1, 1,
        0, 0,
        1, 0
    };
}

// *****************************************************************************

/*******************************************************************************
 
 TODO:  - additional texture parameters
        - check for different formats ( cgcontextdraw)
        - PVR support ( see apple code)
        - mipmapping
 
 
*******************************************************************************/

// *****************************************************************************

//! Texture2D
//! 
//! Create and maintain OpenGL textures made from images

// *****************************************************************************

namespace Meteor 
{
    typedef enum 
    {
        kTexture2DPixelFormat_Automatic = 0,
        kTexture2DPixelFormat_RGBA8888,
        kTexture2DPixelFormat_RGB565,
        kTexture2DPixelFormat_A8
    } 
    Texture2DPixelFormat;

    class Texture2D
    {
        friend class TextureCache;
        
        public:
            //! will delete texture in OpenGL
            ~Texture2D();
        
            //! getter
            const GLuint Name() const;
            
            const float Width() const;
            
            const float Height() const;
            
            //! set the Rectangle that is displayed from the texture
            void SetRect( const Rectangle& rect);
            
            Rectangle Rect() const;
            
            //! set this textures parameter ( clamping etc.)
            void SetParameter( const GLenum name, const GLenum values);
            
            const std::string Filename() const;
        
            //! called for every frame
            void Draw() const;

        private:
            //! storing this texture name generated by glGenTextures
            GLuint mName;
        
            //! dimensions of the associated image
            Vector2D mSize;
            
            //! the format the data is provided in
            Texture2DPixelFormat mPixelFormat;
            
            //! texture mapping coordinates
            std::vector<GLfloat> mTextureCoordinates;
        
            //! stored for deletion, as texture are stored by filename in the
            //! texture cache
            std::string mAssociatedFilename;

            //! load an image and create an opengl texture from it
            void LoadFile( const std::string& filePath);

            //! get image's width, height and pixelformat
            void GetImageProperties( const CGImageRef image);

            //! create an opengl texture for this image
            void CreateTexture( const void* const imageData, 
                                const int width, 
                                const int height);
            
            //! if the image format is RGB565, convert the bytes contained in data
            //! this is mainly bit twiddling "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" 
            //! to "RRRRRGGGGGGBBBBB"
            void TransformImageDataTo565( GLubyte** oldData,
                                          const int width, 
                                          const int height);
            
            //! prevent copying of textures, we don't want the data stored in 
            //! memory twice
            Texture2D( const Texture2D& texture);
            
            Texture2D& operator=( const Texture2D& rhs);
            
            //! to be called from within 'TextureCache' only
            Texture2D();
            
            //! initialize texture with image
            Texture2D( const std::string& filePath);
            
            //! make a texture from existing data in memory
            Texture2D( const void* const data, 
                       const Texture2DPixelFormat format,
                       const Vector2D& size);
            
    }; // end of class Texture2D

} // end of namespace Meteor

#endif // TEXTURE_2D_H
